#include "UdpConnect.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

UdpConnect::UdpConnect(std::string host,int p):ip(host),port(p)
{
    memset(&addr, 0, sizeof(addr));
    fd = -1;
}
//这个是为了新连接构造
UdpConnect::UdpConnect(struct sockaddr_in addrs,int fd_):addr(addrs),fd(fd_)
{
}
UdpConnect::~UdpConnect()
{
}

void UdpConnect::intToByte(int i,char *bytes,int size )
{
    memset(bytes,0,sizeof(char) * size);
    bytes[0] = (char) (0xff & i);
    bytes[1] = (char) ((0xff00 & i) >> 8);
    bytes[2] = (char) ((0xff0000 & i) >> 16);
    bytes[3] = (char) ((0xff000000 & i) >> 24);
    return ;
}
int UdpConnect::bytesToInt(char* bytes,int size)
{
    int addr = bytes[0] & 0xFF;
    addr |= ((bytes[1] << 8) & 0xFF00);
    addr |= ((bytes[2] << 16) & 0xFF0000);
    addr |= ((bytes[3] << 24) & 0xFF000000);
    return addr;
}


int UdpConnect::recv(  void *data, int maxsize ,struct sockaddr_in& clent_addr )
{
    socklen_t len = sizeof(clent_addr);
    int ret = ::recvfrom(fd, data, maxsize, 0, (struct sockaddr*)&clent_addr, &len);  //recvfrom是拥塞函数，没有数据就一直拥塞
    if(ret > 0)
    {
        
    }
    return ret;
}

void UdpConnect::send(  const void *data, int size )
{
    if(fd < 0)
        return;
     ::sendto(fd, data, size, 0, (struct sockaddr*)&addr, sizeof(addr));
}

void UdpConnect::init()
{
    fd= socket(AF_INET, SOCK_DGRAM, 0);
    if(fd< 0)
    {
        printf("create socket fail!\n");
        return ;
    }
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip.c_str());
    addr.sin_port = htons(port);  //端口号，需要网络序转换
    /*
    char buf[8];
    intToByte(1,buf);           //1建立连接
    //生成kcp唯一ID
    int sessid = 111;           //暂时固定某个值吧，后面可变累加值
    intToByte(sessid,buf+4);
    ::sendto(fd, buf, 8, 0, (struct sockaddr*)&addr, sizeof(addr));
    */
}
int UdpConnect::bind()
{
    int  ret;
    fd= socket(AF_INET, SOCK_DGRAM, 0); //AF_INET:IPV4;SOCK_DGRAM:UDP
    if(fd< 0)
    {
        printf("create socket fail!\n");
        return -1;
    }
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip.c_str());
    addr.sin_port = htons(port);  //端口号，需要网络序转换
    ret = ::bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    if(ret < 0)
    {
        printf("socket bind fail!\n");
        return -1;
    }
    return 0;

}
int UdpConnect::put(char* data,int len)
{
     while (lock.test_and_set(std::memory_order_acquire))
         ;
    int n = recvbuf.sputn(data,len);
    lock.clear(std::memory_order_release);;
    return n;
}
int UdpConnect::recv(char* data,int len)
{
     while (lock.test_and_set(std::memory_order_acquire))
         ;
    int n = recvbuf.sgetn(data,len);
    lock.clear(std::memory_order_release);;
    return n;
}



